#ifndef __HANDLEEVENT_H__
#define __HANDLEEVENT_H__

#include "common.h"
#include "parseMessage.h"
#include "sock.h"
#include "epoll.h"

#define MSG_MAXLEN 1024
typedef void*(*HANDLE)(void*);
struct Task
{
	int epollfd_;
	int fd_;
	void* et_;
	HttpEndPoint* endpoint_;
};

class HandleEvent
{
public:

	static void handleConn(void* arg)
	{
		Task* tk = (Task*)arg;
		if (!tk || !tk->fd_)
			return;

		//处理连接
		struct sockaddr_in peer;
		socklen_t peer_len = 0;
		int clientfd = SockOpt::Accept(tk->fd_, (void*)&peer, (void*)&peer_len);
		if (clientfd <= 0)
		{
			LOG_ERROR("FFL[%s:%s:%u] accpet fail sock_fd_:%u, clientfd:%u", LOG_FFL, tk->fd_, clientfd);
		}
		else
		{
      std::cout << "get a link..." << tk->fd_ << ":" << clientfd << std::endl;
			Task* newtk = new Task;
			newtk->epollfd_ = tk->epollfd_;
			newtk->fd_ = clientfd;
			newtk->et_ = (void*)handleRecv;
			EpollOpt::AddEpoll(tk->epollfd_, clientfd, EPOLLIN, (void*)newtk);
		}
	}

	static void handleSend(void* arg)
	{
		Task* tk = (Task*)arg;
		if (!tk || !tk->fd_ || !tk->epollfd_ || !tk->endpoint_)
			return;

		tk->endpoint_->makeResponse();
		tk->endpoint_->sendResponse();

		LOG_INFO("FFL[%s:%s:%u] send finish fd:%d", LOG_FFL, tk->fd_);
		delete tk->endpoint_;
		tk->endpoint_ = nullptr;
		close(tk->fd_);
		delete tk;
		tk = nullptr;
	}

	static void handleRecv(void* arg)
	{
		Task* tk = (Task*)arg;
		if (!tk || !tk->fd_ || !tk->epollfd_)
			return;

		char buff[MSG_LEN] = { 0 };
		int num = SockOpt::Recv(tk->fd_, buff, MSG_LEN - 1, 0);
		if (num > 0)
		{
			if (num >= MSG_MAXLEN)
			{
				buff[MSG_MAXLEN - 1] = '\0';
				num = MSG_MAXLEN;
				LOG_ERROR("FFL[%s:%s:%u] msg len is small");
			}
			else
			{
				buff[num] = '\0';
			}
			//TODO 修改事件为写就绪
			//解析协议，
			tk->endpoint_ = new HttpEndPoint(tk->fd_);
			tk->endpoint_->parseHttpMsg(buff, num);

			tk->et_ = (void*)handleSend;
			EpollOpt::ModEpoll(tk->epollfd_, tk->fd_, EPOLLOUT, tk);
		}
		else if (num == 0)
		{
			std::cout << "client close" << std::endl;
			EpollOpt::DelEpoll(tk->epollfd_, tk->fd_);
			close(tk->fd_);
			delete tk;
		}
		else
		{
			std::cout << "recv fail" << std::endl;
		}

	}
};
  
#endif
